package hotel.controller.room;

import java.io.IOException;
import java.util.List;

import hotel.common.MsgBox;
import hotel.dao.HotelDao;
import hotel.modal.RoomType;
import javafx.beans.binding.Bindings;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Pos;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableView;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableRow;

public class RoomTypeManageController {
	@FXML
	private TableView<RoomType> tableView;
	@FXML
	private TableColumn<RoomType, Integer> roomTypeCol;
	@FXML
	private TableColumn<RoomType, String> typeNameCol;
	@FXML
	private TableColumn<RoomType, Boolean> hourRoomCol;
	@FXML
	private TableColumn<RoomType, Integer> bedNumCol;
	@FXML
	private TableColumn<RoomType, Number> depositCol;
	@FXML
	private TableColumn<RoomType, Number> priceCol;
	@FXML
	private Button btnAdd;
	
	@FXML
    public void initialize() {
		
		// 设置表格生成规则
		setCellFactory();

		// 加载数据
		loadData();
		
	}
	
	private void setCellFactory() {
		
		roomTypeCol.setCellFactory(col -> new TableCell<RoomType, Integer>() {
			@Override
			protected void updateItem(Integer item, boolean empty) {
				super.updateItem(item, empty);
				if (empty == true)
					setText(null);
				else 
					setText(item.toString());
				setAlignment(Pos.CENTER);
			}
		});
		
		typeNameCol.setCellFactory(col -> new TableCell<RoomType, String>() {
			@Override
			protected void updateItem(String item, boolean empty) {
				super.updateItem(item, empty);
				if (empty == true)
					setText(null);
				else
					setText(item);
				setAlignment(Pos.CENTER);
			}
		});
		
		hourRoomCol.setCellFactory(col -> new TableCell<RoomType, Boolean>() {
			@Override
			protected void updateItem(Boolean item, boolean empty) {
				super.updateItem(item, empty);
				if (empty == true)
					setText(null);
				else if (item == true)
					setText("是");
				else
					setText("否");
				setAlignment(Pos.CENTER);
			}
		});
		
		depositCol.setCellFactory(col -> new TableCell<RoomType, Number>() {
			@Override
			protected void updateItem(Number item, boolean empty) {
				super.updateItem(item, empty);
				if (empty == true)
					setText(null);
				else if (item == null)
					setText(null);
				else
					setText(String.format("%.2f", item));
				setAlignment(Pos.CENTER);
			}
		});
		
		priceCol.setCellFactory(col -> new TableCell<RoomType, Number>() {
			@Override
			protected void updateItem(Number item, boolean empty) {
				super.updateItem(item, empty);
				if (empty == true)
					setText(null);
				else if (item == null)
					setText(null);
				else
					setText(String.format("%.2f", item));
				setAlignment(Pos.CENTER);
			}
		});
		
		bedNumCol.setCellFactory(col -> new TableCell<RoomType, Integer>() {
			@Override
			protected void updateItem(Integer item, boolean empty) {
				super.updateItem(item, empty);
				if (empty == true)
					setText(null);
				else 
					setText(item.toString());
				setAlignment(Pos.CENTER);
			}
		});

		// 设置表格行右键菜单
		tableView.setRowFactory(new Callback<TableView<RoomType>, TableRow<RoomType>>() {
			@Override
			public TableRow<RoomType> call(TableView<RoomType> tableView) {
				final TableRow<RoomType> row = new TableRow<>();

				final ContextMenu rowMenu = new ContextMenu();
				MenuItem changeItem = new MenuItem("更改");

				changeItem.setOnAction(new EventHandler<ActionEvent>() {
					@Override
					public void handle(ActionEvent event) {
						RoomType roomType = row.getItem();
						changeValue(roomType);
					}
				});

				MenuItem removeItem = new MenuItem("删除");

				removeItem.setOnAction(new EventHandler<ActionEvent>() {
					@Override
					public void handle(ActionEvent event) {
						Boolean ret = MsgBox.showConfirmationDialog("删除确认", null, "你即将删除一个客房类型，是否继续？");
						if(!ret) return;
						RoomType roomType = row.getItem();
						if (HotelDao.delete(roomType)) {
							tableView.getItems().remove(roomType);
							tableView.refresh();
						} else {
							MsgBox.showErrorDialog("错误", null, "删除失败！");
						}
					}
				});

				rowMenu.getItems().addAll(changeItem, removeItem);

				row.setOnMouseClicked(event -> { // 鼠标双击
					if (event.getClickCount() == 2 && (!row.isEmpty())) {
						RoomType roomType = row.getItem();
						changeValue(roomType);
					}
				});

				// only display context menu for non-null items:
				row.contextMenuProperty().bind(Bindings.when(Bindings.isNotNull(row.itemProperty())).then(rowMenu)
						.otherwise((ContextMenu) null));
				return row;
			}
		});
	}
	
	
	public void loadData() {
		ObservableList<RoomType> data = tableView.getItems();
		data.clear();
		List<RoomType> roomTypeList = HotelDao.getAllRoomType();
		if(roomTypeList != null && roomTypeList.size() > 0) {
			data.addAll(roomTypeList);
		}
		tableView.refresh();
	}
	
	// Event Listener on Button[#btnAdd].onAction
		@FXML
		public void onBtnAddAction(ActionEvent event) {
			RoomType roomType = new RoomType();
			roomType.setTypeId(HotelDao.getNextRoomTypeId());
			if(roomType == null || roomType.getTypeId() == 0) {
				MsgBox.showErrorDialog("错误", null, "生成房间类型编号失败！");
				return;
			}
			FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/hotel/view/room/RoomTypeChange.fxml"));
			try {
				Parent root = (Parent) fxmlLoader.load();
				RoomTypeChangeController controller = fxmlLoader.<RoomTypeChangeController>getController();
				controller.setAddMode();
				controller.setInitData(roomType); // 向子窗口传递数据
				Stage stage = new Stage();
				stage.setScene(new Scene(root));
				stage.setTitle("房间类型信息添加");
				stage.setResizable(false);
				stage.initModality(Modality.APPLICATION_MODAL);
				stage.showAndWait(); // 显示窗口并等待用户操作
				ObservableList<RoomType> data = tableView.getItems();
				if (roomType.isModified()) { // 判断是否被修改
					if (HotelDao.add(roomType)) {
						int index = data.size();
						data.add(index, roomType);
						tableView.getSelectionModel().select(index);
					}else {
						MsgBox.showErrorDialog("错误", "房间类型信息修改失败！", "没有成功写入数据库！");
					}
				}
				tableView.refresh(); // 刷新表格
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		private void changeValue(RoomType roomType) {
			FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/hotel/view/room/RoomTypeChange.fxml"));
			try {
				Parent root = (Parent) fxmlLoader.load();
				RoomTypeChangeController controller = fxmlLoader.<RoomTypeChangeController>getController();
				controller.setInitData(roomType); // 向子窗口传递数据
				Stage stage = new Stage();
				stage.setScene(new Scene(root));
				stage.setTitle("更改房间类型信息");
				stage.setResizable(false);
				stage.initModality(Modality.APPLICATION_MODAL);
				stage.showAndWait(); // 显示窗口并等待用户操作
				if (roomType.isModified()) { // 判断是否被修改
					if (!HotelDao.update(roomType)) {
						MsgBox.showErrorDialog("错误", "房间类型信息修改失败！", "没有成功写入数据库！");
					}
				}
				tableView.refresh(); // 刷新表格
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

}
